package com.hunt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hunt.dao.TransactionCalendarMapper;
import com.hunt.model.app.TransactionCalendar;
import com.hunt.model.entity.DDXMarket;
import com.hunt.model.entity.DDXRankingMarket;
import com.hunt.model.entity.StockDDX;
import com.hunt.service.AppDDXRankingService;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AppDDXRankingServiceImpl implements AppDDXRankingService {

    @Autowired
    private MongoTemplate stockDDXHistoryMongoTemplate;
    @Autowired
    private MongoTemplate stockDDXHistoryTotalMongoTemplate;
    @Autowired
    private MongoTemplate stockDDXHistoryTotal3MongoTemplate;
    @Autowired
    private MongoTemplate stockDDXHistoryTotal5MongoTemplate;
    @Autowired
    private MongoTemplate stockDDXHistoryTotal10MongoTemplate;
    @Autowired
    private MongoTemplate stockDDXHistoryTotal60MongoTemplate;
    @Autowired
    private MongoTemplate blockDDXHistoryTotalMongoTemplate;
    @Autowired
    private JedisPool jedisPool;

    @Autowired
    AppDDXRankingService appDDXRankingService;

    @Autowired
    private TransactionCalendarMapper transactionCalendarMapper;
    @Resource
    private RedisTemplate stringredisTemplate;

    @Override
    public DDXMarket getStockDDXBySort(String dbName,String sortNumber, Integer position, Integer size) {
        Jedis jedis = null;
        DDXMarket ddxMarket = new DDXMarket();
        List<DDXRankingMarket> marketList = null;
        Long stockCount = null;
        try {
            jedis = jedisPool.getResource();
            stockCount = jedis.llen(dbName);
            if(sortNumber.trim().equals("0")) {
                List<String> stockListStr = jedis.lrange(dbName, position, position + size - 1);
                if (stockListStr == null ||stockListStr.size() == 0) {
                    ddxMarket.setTotal(stockCount.intValue());
                    return ddxMarket;
                }
                marketList = JSONArray.parseArray(stockListStr.toString(), DDXRankingMarket.class);
                for(DDXRankingMarket dm:marketList){
                    Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", dm.getStockCode());
                    JSONObject jo = JSON.parseObject((String) obj);
                    if(null==jo){
                        dm.setHlPercent("0.00%");
                    }else {
                        dm.setHlPercent(jo.getString("hlPercent"));
                    }

                }
                ddxMarket.setTotal(Integer.valueOf(String.valueOf(stockCount)));
                ddxMarket.setMarketList(marketList);
            } else if (sortNumber.trim().equals("1")){
                int start = Integer.valueOf(String.valueOf(stockCount)) - position - size;
                int end = Integer.valueOf(String.valueOf(stockCount)) - position;
                if (position != 0) {
                    end = end - 1;
                }
                List<String> stockListSort = jedis.lrange(dbName, start <= 0 ? 0:start, end <= 0 ? 0:end);
                if (stockListSort == null || stockListSort.size() == 0) {
                    ddxMarket.setTotal(stockCount.intValue());
                    return ddxMarket;
                }
                marketList = JSONArray.parseArray(stockListSort.toString(), DDXRankingMarket.class);
                for(DDXRankingMarket dm:marketList){
                    Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", dm.getStockCode());
                    JSONObject jo = JSON.parseObject((String) obj);
                    if(null==jo){
                        dm.setHlPercent("0.00%");
                    }else {
                        dm.setHlPercent(jo.getString("hlPercent"));
                    }
                }
                Collections.reverse(marketList);
                ddxMarket.setTotal(stockCount.intValue());
                ddxMarket.setMarketList(marketList);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null){
                jedis.close();
            }
        }
        return ddxMarket;
    }

    @Override
    public List<DDXRankingMarket> getBlockDDXBySort(String sortNumber, Integer position, Integer size) {
        Jedis jedis = null;
        List<DDXRankingMarket> ddxRankingPlates = null;
        try {
            jedis = jedisPool.getResource();
            Long blockRankLen = jedis.llen("DDX_BLOCK_RANK");
            List<String> ddx_block_rank = jedis.lrange("DDX_BLOCK_RANK", 0, blockRankLen);
            if (ddx_block_rank == null || ddx_block_rank.size() < 30){
                return new ArrayList<>();
            }
            ddxRankingPlates = JSONArray.parseArray(ddx_block_rank.toString(), DDXRankingMarket.class);
            Collections.sort(ddxRankingPlates);
            if(sortNumber.trim().equals("2")){
                for (int i = 0; i < ddxRankingPlates.size(); i++) {
                    ddxRankingPlates.get(i).setRanking(String.valueOf(i+1));
//                    Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", ddxRankingPlates.get(i).getStockCode());
//                    JSONObject jo = JSON.parseObject((String) obj);
//                    ddxRankingPlates.get(i).setHlPercent(jo.getString("hlPercent"));
                }


            } else if (sortNumber.trim().equals("3")){
                Collections.reverse(ddxRankingPlates);
                for (int i = 0; i < ddxRankingPlates.size(); i++) {
                    ddxRankingPlates.get(i).setRanking(String.valueOf(i+1));
//                    Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", ddxRankingPlates.get(i).getStockCode());
//                    JSONObject jo = JSON.parseObject((String) obj);
//                    ddxRankingPlates.get(i).setHlPercent(jo.getString("hlPercent"));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null){
                jedis.close();
            }
        }
        return ddxRankingPlates!=null?ddxRankingPlates.subList(0,30):new ArrayList<>();
    }

    @Override
    public DDXMarket getStockDDXRankingByStockCode(String stockCode) {
        Jedis jedis = null;
        DDXMarket ddxMarket = null;
        List<DDXRankingMarket> marketList = null;
        Long stockCount = null;
        try {
            jedis = jedisPool.getResource();
            ddxMarket = new DDXMarket();
            stockCount = jedis.llen("DDX_STOCK_RANK");
            List<String> stockListStr = jedis.lrange("DDX_STOCK_RANK", 0, stockCount - 1);
            if (stockListStr == null ||stockListStr.size() == 0) {
                ddxMarket.setTotal(stockCount.intValue());
                return ddxMarket;
            }
            marketList = JSONArray.parseArray(stockListStr.toString(), DDXRankingMarket.class);
            marketList = marketList.stream().filter(
                    market -> stockCode.equals(market.getStockCode())).collect(Collectors.toList());
            ddxMarket.setTotal(marketList.size());
            ddxMarket.setMarketList(marketList);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null){
                jedis.close();
            }
        }
        return ddxMarket;
    }

    @Override
    public List<StockDDX> getStockDDXByStockCode(String stockCode) {
        List<StockDDX> list = null;
        Query query = new Query();
        query.with(new Sort(Sort.Direction.ASC, "_id"));
        list = stockDDXHistoryMongoTemplate.find(query, StockDDX.class, stockCode);
        Date date = new Date();
        Date date0 = null;
        String dateString = DateUtils.formatDate(date, "yyyyMMdd");
        try {
            SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmmss");
            date0 = sdf.parse(dateString + "093000");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if(date.getTime() < date0.getTime()) {
            return list;
        }
        TransactionCalendar transactionCalendar = transactionCalendarMapper.findByCalDate(dateString);
        boolean isOpen = "1".equals(transactionCalendar.getIs_open());
        Query query0 = new Query();
        query0.addCriteria(Criteria.where("_id").is(dateString));
        StockDDX stockDDX = stockDDXHistoryMongoTemplate.findOne(query0, StockDDX.class, stockCode);
        DDXMarket ddxMarket = getStockDDXRankingByStockCode(stockCode);
        if (isOpen && stockDDX == null && ddxMarket != null && ddxMarket.getMarketList().size() != 0) {
            DDXRankingMarket ddxRankingMarket = ddxMarket.getMarketList().get(0);
            stockDDX = new StockDDX();
            stockDDX.set_id(dateString);
            stockDDX.setDdx(ddxRankingMarket.getDdx());
            list.add(stockDDX);
        }
        return list;
    }

    @Override
    public DDXMarket getHistoryDDX(String type,String date, String sortNumber, Integer position, Integer size) {
        Query query = new Query();
        DDXMarket ddxMarket= new DDXMarket();
        List<DDXRankingMarket> stockDDXList =new ArrayList<>();

        query.skip(position);
        query.limit(size);
        if (sortNumber.equals("0")||sortNumber.equals("2")){
            query.with(new Sort( Sort.Direction.ASC, "_id"));

        }
        if (sortNumber.equals("1")||sortNumber.equals("3")){
            query.with(new Sort( Sort.Direction.DESC, "_id"));
        }
        if(type.equals("0")&&sortNumber.equals("1")){
            stockDDXList = stockDDXHistoryTotalMongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotalMongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(type.equals("0")&&sortNumber.equals("0")){
            stockDDXList = stockDDXHistoryTotalMongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotalMongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(type.equals("1")){
            stockDDXList =  stockDDXHistoryTotal3MongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotal3MongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(type.equals("2")){
            stockDDXList =  stockDDXHistoryTotal5MongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotal5MongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(type.equals("3")){
            stockDDXList =  stockDDXHistoryTotal10MongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotal10MongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(type.equals("4")){
            stockDDXList =  stockDDXHistoryTotal60MongoTemplate.find(query, DDXRankingMarket.class, date);
            long count = stockDDXHistoryTotal60MongoTemplate.count(new Query(), DDXRankingMarket.class, date);
            ddxMarket.setTotal(Math.toIntExact(count));
        }
        if(sortNumber.equals("2")){
            stockDDXList = blockDDXHistoryTotalMongoTemplate.find(query, DDXRankingMarket.class, date);

            ddxMarket.setTotal(30);
        }
        if(sortNumber.equals("3")){
            stockDDXList = blockDDXHistoryTotalMongoTemplate.find(query, DDXRankingMarket.class, date);
            ddxMarket.setTotal(30);
        }
        if(sortNumber.equals("3")||sortNumber.equals("2")){
            for(DDXRankingMarket ddx:stockDDXList){
                Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", ddx.getStockCode()+".ti");
                JSONObject jo = JSON.parseObject((String) obj);
                if(null!=obj){
                    ddx.setHlPercent(jo.getString("hlPercent"));
                }else {
                    ddx.setHlPercent("0.00%");
                }

            }
        }else {
            for(DDXRankingMarket ddx:stockDDXList){
                Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data", ddx.getStockCode());
                JSONObject jo = JSON.parseObject((String) obj);
                if(null!=obj){
                    ddx.setHlPercent(jo.getString("hlPercent"));
                }else {
                    ddx.setHlPercent("0.00%");
                }

            }
        }

        ddxMarket.setMarketList(stockDDXList);

        return ddxMarket;
    }

    public List<StockDDX> getHistoryStockDDX(String stockCode, String date) {
        Query query = new Query();
        List<StockDDX> stockDDXList = stockDDXHistoryTotalMongoTemplate.find(query, StockDDX.class, date);

        return null;
    }

}
